#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
#import <Flutter/Flutter.h>
#import "Macros.h"

#define channelOnPeropheralView @"peripheralView"

@interface AppDelegate ()

@property (strong, nonatomic) NSTimer *scanTimer;

@property (copy, nonatomic) NSString *kcbmCode;

@property (strong, nonatomic) NSMutableDictionary *dataDict;

@property (copy, nonatomic) FlutterResult result;

@end

@implementation AppDelegate {
    NSString *receiveMsg;
    NSString *sendStuID;//发送学员id
    NSString *sendA2Message;//发送A2消息
    NSTimer *timerA2;
    NSTimer *timerT1;
}

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [GeneratedPluginRegistrant registerWithRegistry:self];
    // Override point for customization after application launch.
    
    self.dataDict = [NSDictionary dictionary].mutableCopy;
    
    
    FlutterViewController *controller = (FlutterViewController *)self.window.rootViewController;
    FlutterMethodChannel *shareChannel = [FlutterMethodChannel methodChannelWithName:@"cn.zchope" binaryMessenger:controller];
    [shareChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
        if ([@"oneAct" isEqualToString:call.method]) {
            NSDictionary *dic = call.arguments;
            NSString *studentCode = dic[@"deviceName"];
            self.bluetoothName = studentCode;
            NSLog(@"%@",dic[@"data"]);
            NSString *jsonString = dic[@"data"];
            NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
            self.dataDict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
            NSLog(@"%@",self.dataDict);
            // {"p3":"130102199403090310","p2":"胡少康","p1":"3931514965129650","p4":"1212120000","p5":"157535"}
            self.result = result;
            NSLog(@"==-=-=-=-=-=-=-=-=-=%@",result);
            [self initBabyBluetooth];
        }
        if ([@"viewVersionNumber" isEqualToString:call.method]) {
            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"已有最新版本发布，是否更新?" preferredStyle:(UIAlertControllerStyleAlert)];
            UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
                [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/app/id1380512641"]];
            }];
            UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleCancel) handler:nil];
            [alertController addAction:okAction];
            [alertController addAction:cancelAction];
            [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
        }
    }];
    
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)stopScan {//20秒停止扫描
    [_baby cancelScan];
    [_scanTimer invalidate];
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    dic[@"state"] = @"4";
    //    [kNOTIFICATION_DEFAULT postNotificationName:@"state" object:dic];
    [self queryState:dic];
}

- (void)initBabyBluetooth {
    receiveMsg = @"";
    // 初始化BabyBluetooth蓝牙库
    _baby = [BabyBluetooth shareBabyBluetooth];
    //设置蓝牙委托
    [self babyDelegate];
    //停止之前的连接
    //    [_baby cancelAllPeripheralsConnection];
    //设置委托后直接可以使用，无需等待CBCentralManagerStatePoweredOn状态。
    _baby.scanForPeripherals().begin();
    
}

- (void)babyDelegate {
    __weak typeof(self) weakSelf = self;
    [_baby setBlockOnCentralManagerDidUpdateState:^(CBCentralManager *central) {
        if (central.state == CBCentralManagerStatePoweredOn) {
        }
    }];
    //设置扫描到设备的委托
    [_baby setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
        if (self->_scanTimer == nil) {
            self->_scanTimer = [NSTimer timerWithTimeInterval:20.f target:weakSelf selector:@selector(stopScan) userInfo:nil repeats:NO];
            [[NSRunLoop mainRunLoop] addTimer:weakSelf.scanTimer forMode:NSDefaultRunLoopMode];
        }
        NSLog(@"搜索到了设备:%@",peripheral.name);
        self->_currPeripheral = peripheral;
        //判断是否匹配二维码中的名称
        if ([peripheral.name isEqualToString:weakSelf.bluetoothName]) {
            [weakSelf beginConnect];
            [weakSelf.baby cancelScan];
            [weakSelf.scanTimer invalidate];
        }
    }];
    //设置发现设备的Services的委托
    [_baby setBlockOnDiscoverServices:^(CBPeripheral *peripheral, NSError *error) {
        //        for (CBService *service in peripheral.services) {
        //            NSLog(@"搜索到服务:%@",service.UUID.UUIDString);
        //        }
    }];
    //设置发现设备service的Characteristics的委托
    [_baby setBlockOnDiscoverCharacteristics:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        //        NSLog(@"===service name:%@",service.UUID);
        //        for (CBCharacteristic *c in service.characteristics) {
        //            NSLog(@"charateristic name is :%@",c.UUID);
        //        }
    }];
    //设置读取characteristics的委托
    [_baby setBlockOnReadValueForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        NSLog(@"characteristic name:%@ value is:%@",characteristics.UUID,characteristics.value);
    }];
    //设置发现characteristics的descriptors的委托
    [_baby setBlockOnDiscoverDescriptorsForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) {
        //        NSLog(@"===characteristic name:%@",characteristic.service.UUID);
        //        for (CBDescriptor *d in characteristic.descriptors) {
        //            NSLog(@"CBDescriptor name is :%@",d.UUID);
        //        }
    }];
    //设置读取Descriptor的委托
    [_baby setBlockOnReadValueForDescriptors:^(CBPeripheral *peripheral, CBDescriptor *descriptor, NSError *error) {
        NSLog(@"Descriptor name:%@ value is:%@",descriptor.characteristic.UUID, descriptor.value);
    }];
    //设置查找设备的过滤器
    [_baby setFilterOnDiscoverPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
        //最常用的场景是查找某一个前缀开头的设备
        //        if ([peripheralName hasPrefix:@"Pxxxx"] ) {
        //            return YES;
        //        }
        //        return NO;
        //设置查找规则是名称大于0 ， the search rule is peripheral.name length > 0
        return peripheralName.length >0;
    }];
    [_baby setBlockOnCancelAllPeripheralsConnectionBlock:^(CBCentralManager *centralManager) {
        NSLog(@"setBlockOnCancelAllPeripheralsConnectionBlock");
    }];
    [_baby setBlockOnCancelScanBlock:^(CBCentralManager *centralManager) {
        NSLog(@"setBlockOnCancelScanBlock");
    }];
    /*设置babyOptions
     参数分别使用在下面这几个地方，若不使用参数则传nil
     - [centralManager scanForPeripheralsWithServices:scanForPeripheralsWithServices options:scanForPeripheralsWithOptions];
     - [centralManager connectPeripheral:peripheral options:connectPeripheralWithOptions];
     - [peripheral discoverServices:discoverWithServices];
     - [peripheral discoverCharacteristics:discoverWithCharacteristics forService:service];
     该方法支持channel版本:
     [baby setBabyOptionsAtChannel:<#(NSString *)#> scanForPeripheralsWithOptions:<#(NSDictionary *)#> connectPeripheralWithOptions:<#(NSDictionary *)#> scanForPeripheralsWithServices:<#(NSArray *)#> discoverWithServices:<#(NSArray *)#> discoverWithCharacteristics:<#(NSArray *)#>]
     */
    //示例:
    //扫描选项->CBCentralManagerScanOptionAllowDuplicatesKey:忽略同一个Peripheral端的多个发现事件被聚合成一个发现事件
    NSDictionary *scanForPeripheralsWithOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@YES};
    //连接设备->
    [_baby setBabyOptionsWithScanForPeripheralsWithOptions:scanForPeripheralsWithOptions connectPeripheralWithOptions:nil scanForPeripheralsWithServices:nil discoverWithServices:nil discoverWithCharacteristics:nil];
}

- (void)beginConnect {
    [_baby cancelScan];
    //停止之前的连接
    [_baby cancelAllPeripheralsConnection];
    
    [self babyDelegateForTransfer];
    //开始扫描设备
    [self performSelector:@selector(loadData) withObject:nil afterDelay:2];
}

- (void)loadData {
    _baby.having(_currPeripheral).and.channel(channelOnPeropheralView).then.connectToPeripherals().discoverServices().discoverCharacteristics().readValueForCharacteristic().discoverDescriptorsForCharacteristic().readValueForDescriptors().begin();
}

//babyDelegate
-(void)babyDelegateForTransfer{
    __weak typeof(self)weakSelf = self;
    
    BabyRhythm *rhythm = [[BabyRhythm alloc]init];
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    
    //设置设备连接成功的委托,同一个baby对象，使用不同的channel切换委托回调
    [_baby setBlockOnConnectedAtChannel:channelOnPeropheralView block:^(CBCentralManager *central, CBPeripheral *peripheral) {
        self->_isConnected = YES;
        dic[@"state"] = @"1";
        //        [kNOTIFICATION_DEFAULT postNotificationName:@"state" object:dic];
        [weakSelf queryState:dic];
    }];
    //设置设备连接失败的委托
    [_baby setBlockOnFailToConnectAtChannel:channelOnPeropheralView block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        self->_isConnected = NO;
        dic[@"state"] = @"2";
        //        [kNOTIFICATION_DEFAULT postNotificationName:@"state" object:dic];
        [weakSelf queryState:dic];
    }];
    //设置设备断开连接的委托
    [_baby setBlockOnDisconnectAtChannel:channelOnPeropheralView block:^(CBCentralManager *central, CBPeripheral *peripheral, NSError *error) {
        self->_isConnected = NO;
        dic[@"state"] = @"3";
        //        [kNOTIFICATION_DEFAULT postNotificationName:@"state" object:dic];
        [weakSelf queryState:dic];
        
        //断开重连
        //        [weakSelf initBabyBluetooth];
        
        NSLog(@"%@", peripheral.identifier.UUIDString);
        
        //        [central connectPeripheral:peripheral options:nil];
        
        //        [NSTimer scheduledTimerWithTimeInterval: 3.0 target:weakSelf selector: @selector(reconnect) userInfo: nil repeats: YES];
    }];
    //设置发现设备的Services的委托
    [_baby setBlockOnDiscoverServicesAtChannel:channelOnPeropheralView block:^(CBPeripheral *peripheral, NSError *error) {
        //        for (CBService *s in peripheral.services) {
        ///插入section到tableview
        //            [weakSelf insertSectionToTableView:s];
        //        }
        [rhythm beats];
    }];
    //设置发现设service的Characteristics的委托
    [_baby setBlockOnDiscoverCharacteristicsAtChannel:channelOnPeropheralView block:^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        NSLog(@"===service name:%@",service.UUID);
        [kNOTIFICATION_DEFAULT addObserver:weakSelf selector:@selector(receiveWriteUUID:) name:@"write" object:nil];
    }];
    //设置读取characteristics的委托
    [_baby setBlockOnReadValueForCharacteristicAtChannel:channelOnPeropheralView block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        NSLog(@"characteristic name:%@ value is:%@",characteristics.UUID,characteristics.value);
        NSLog(@"%@", characteristics.UUID.UUIDString);
        if ([characteristics.UUID.UUIDString isEqualToString:NOTIFY_UUID] || [characteristics.UUID.UUIDString isEqualToString:NOTIFY_UUID1]) {
            self->_currPeripheral = peripheral;
            self->_readCharacter = characteristics;
            [weakSelf sendNoti:dic];
        }
    }];
    //设置发现characteristics的descriptors的委托
    [_baby setBlockOnDiscoverDescriptorsForCharacteristicAtChannel:channelOnPeropheralView block:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) {
        //        NSLog(@"===characteristic name:%@",characteristic.service.UUID);
        //        for (CBDescriptor *d in characteristic.descriptors) {
        //            NSLog(@"CBDescriptor name is :%@",d.UUID);
        //        }
    }];
    //设置读取Descriptor的委托
    [_baby setBlockOnReadValueForDescriptorsAtChannel:channelOnPeropheralView block:^(CBPeripheral *peripheral, CBDescriptor *descriptor, NSError *error) {
        NSLog(@"Descriptor name:%@ value is:%@",descriptor.characteristic.UUID, descriptor.value);
    }];
    //读取rssi的委托
    [_baby setBlockOnDidReadRSSI:^(NSNumber *RSSI, NSError *error) {
        NSLog(@"setBlockOnDidReadRSSI:RSSI:%@",RSSI);
    }];
    //设置beats break委托
    [rhythm setBlockOnBeatsBreak:^(BabyRhythm *bry) {
        //        NSLog(@"setBlockOnBeatsBreak call");
    }];
    //设置beats over委托
    [rhythm setBlockOnBeatsOver:^(BabyRhythm *bry) {
        NSLog(@"setBlockOnBeatsOver call");
    }];
    //扫描选项->CBCentralManagerScanOptionAllowDuplicatesKey:忽略同一个Peripheral端的多个发现事件被聚合成一个发现事件
    NSDictionary *scanForPeripheralsWithOptions = @{CBCentralManagerScanOptionAllowDuplicatesKey:@YES};
    NSDictionary *connectOptions = @{CBConnectPeripheralOptionNotifyOnConnectionKey:@YES,
                                     CBConnectPeripheralOptionNotifyOnDisconnectionKey:@YES,
                                     CBConnectPeripheralOptionNotifyOnNotificationKey:@YES};
    [_baby setBabyOptionsAtChannel:channelOnPeropheralView scanForPeripheralsWithOptions:scanForPeripheralsWithOptions connectPeripheralWithOptions:connectOptions scanForPeripheralsWithServices:nil discoverWithServices:nil discoverWithCharacteristics:nil];
}

- (void)sendNoti:(NSMutableDictionary *)dic {
    [_baby notify:_currPeripheral characteristic:_readCharacter block:^(CBPeripheral *peripheral, CBCharacteristic *characteristics, NSError *error) {
        if ([characteristics.UUID.UUIDString isEqualToString:NOTIFY_UUID] || [characteristics.UUID.UUIDString isEqualToString:NOTIFY_UUID1]) {
            [self receiveMessage:characteristics.value :dic];
        }
    }];
}


- (void)receiveMessage:(NSData *)data :(NSMutableDictionary *)dic {
    NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    if ([s containsString:@"{"] && ![s containsString:@"}"]) {//只有开头
        if (receiveMsg != nil) {
            receiveMsg = @"";
        }
        receiveMsg = [receiveMsg stringByAppendingString:s];
    } else if (![s containsString:@"}"] && ![s containsString:@"{"]) {//中间
        receiveMsg = [receiveMsg stringByAppendingString:s];
    } else if ([s containsString:@"}"] && ![s containsString:@"{"]) {//只有结尾
        receiveMsg = [receiveMsg stringByAppendingString:s];
        if ([receiveMsg containsString:@"{"] && [receiveMsg containsString:@"}"]) {
            dic[@"message"] = receiveMsg;
            //收到消息
            //            [kNOTIFICATION_DEFAULT postNotificationName:@"message" object:dic];
            [self receive:dic];
        }
        receiveMsg = @"";
    } else if ([s containsString:@"{"] && [s containsString:@"}"]) {
        NSUInteger index = [s rangeOfString:@"{"].location;
        NSUInteger index1 = [s rangeOfString:@"}"].location;
        if (index < index1) {
            receiveMsg = [receiveMsg stringByAppendingString:s];
            dic[@"message"] = receiveMsg;
            //收到消息
            //            [kNOTIFICATION_DEFAULT postNotificationName:@"message" object:dic];
            [self receive:dic];
        } else {
            //            NSString *s1 = [s substringWithRange:NSMakeRange(0, index1 + 1)];
            receiveMsg = [receiveMsg stringByAppendingString:s];
            dic[@"message"] = receiveMsg;
            //收到消息
            //            [kNOTIFICATION_DEFAULT postNotificationName:@"message" object:dic];
            [self receive:dic];
            receiveMsg = @"";
            //            s1 = [s substringWithRange:NSMakeRange(index1 + 1, s.length - (index1 + 1))];
            receiveMsg = [receiveMsg stringByAppendingString:s];
        }
    }
}

- (void)receiveWriteUUID:(NSNotification *)noti {
    _writeCharacter = [noti object];
}


//发送数据
- (void)send:(NSString *)s {
    if (!s || [s isEqualToString:@""]) {
        //        [[HTKVNProgress shared] toast:@"发送内容为空"];
    } else {
        if (_writeCharacter == nil) {
            //            [[HTKVNProgress shared] error:@"特征值为空"];
            NSLog(@"特征值为空");
        } else {
            NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding];
            // 分包发送
            int QD_BLE_SEND_MAX_LEN = 20;
            for (int i = 0; i < [data length]; i += QD_BLE_SEND_MAX_LEN) {
                // 预加 最大包长度，如果依然小于总数据长度，可以取最大包数据大小
                if ((i + QD_BLE_SEND_MAX_LEN) < [data length]) {
                    NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, QD_BLE_SEND_MAX_LEN];
                    NSData *subData = [data subdataWithRange:NSRangeFromString(rangeStr)];
                    [_currPeripheral writeValue:subData forCharacteristic:_writeCharacter type:CBCharacteristicWriteWithResponse];
                    //根据接收模块的处理能力做相应延时
                    usleep(20 * 1000);
                } else {
                    NSString *rangeStr = [NSString stringWithFormat:@"%i,%i", i, (int)([data length] - i)];
                    NSData *subData = [data subdataWithRange:NSRangeFromString(rangeStr)];
                    [_currPeripheral writeValue:subData forCharacteristic:_writeCharacter type:CBCharacteristicWriteWithResponse];
                    usleep(20 * 1000);
                }
            }
        }
    }
}

- (void)disconnect {
    if (_currPeripheral != nil) {
        [_baby cancelPeripheralConnection:_currPeripheral];
    } else {
        [_baby cancelAllPeripheralsConnection];
    }
    _bluetoothName = nil;
}




- (void)queryState:(NSMutableDictionary *)noti {
    NSMutableDictionary *dic = noti;
    if ([dic[@"state"] isEqualToString:@"1"]) {//连接成功
        NSLog(@"连接成功");
        //        hasConnected = YES;
        //        if (timerT1 == nil) {
        //            timerT1 = [NSTimer timerWithTimeInterval:30.f target:self selector:@selector(cutDownConnectAndBack) userInfo:nil repeats:NO];
        //            [[NSRunLoop mainRunLoop] addTimer:timerT1 forMode:NSDefaultRunLoopMode];
        //        }
    } else if ([dic[@"state"] isEqualToString:@"2"]) {//连接失败
        NSLog(@"连接失败");
        [self disconnect];
        //        if (hasConnected) {
        //            [self cutDownConnectAndBack];
        //        }
        
    } else if ([dic[@"state"] isEqualToString:@"3"]) {//断开连接
        NSLog(@"连接已断开");
        [self disconnect];
        //        if (hasConnected) {
        //            [self cutDownConnectAndBack];
        //        }
        
    } else if ([dic[@"state"] isEqualToString:@"4"]) {//未扫描到设备
        NSLog(@"未扫描到设备");
        [self disconnect];
        //        [self cutDownConnectAndBack];
    } else {
        
    }
}





- (void)receive:(NSMutableDictionary *)noti {//接收消息
    NSMutableDictionary *dic = noti;
    NSData *data = [dic[@"message"] dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
    if (jsonDic != nil) {
        if ([jsonDic[@"mt"] isEqualToString:@"A1"]) {
            NSLog(@"收到A1");
        } else if ([jsonDic[@"mt"] isEqualToString:@"A2"]) {
            NSLog(@"收到A2");
            //            if (!hasReceivedStuID) {
            //                [timerA2 invalidate];
            //
            //                hasReceivedStuID = YES;
            //            }
        } else if ([jsonDic[@"mt"] isEqualToString:@"T1"]) {
            NSLog(@"收到T1");
            
            NSString *appStudentid = self.dataDict[@"p1"];
            NSString *zdStudentid = jsonDic[@"p12"];
            
            // 传输学员信息
            [self.dataDict setObject:@"A2" forKey:@"mt"];
            if (zdStudentid == nil) {// 终端没有学员信息则上传
                sendStuID = appStudentid;
                NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self.dataDict options:0 error:nil];
                sendA2Message = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                if (timerA2 == nil) {
                    timerA2 = [NSTimer timerWithTimeInterval:5.0f target:self selector:@selector(sendA2) userInfo:nil repeats:YES];
                    [[NSRunLoop mainRunLoop] addTimer:timerA2 forMode:NSDefaultRunLoopMode];
                }
                NSLog(@"1上传学员信息");
            } else if ([appStudentid isEqualToString:zdStudentid]) {
                // 学员信息一致不操作
                
            } else {
                // 学员信息不一致
                sendStuID = appStudentid;
                NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self.dataDict options:0 error:nil];
                sendA2Message = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
                if (timerA2 == nil) {
                    timerA2 = [NSTimer timerWithTimeInterval:5.0f target:self selector:@selector(sendA2) userInfo:nil repeats:YES];
                    [[NSRunLoop mainRunLoop] addTimer:timerA2 forMode:NSDefaultRunLoopMode];
                }
                NSLog(@"2上传学员信息");
            }
            // 参数12，表示是否收到学员信息
            NSString *studentID = jsonDic[@"p12"];
            if (studentID != nil && [studentID isEqualToString:sendStuID]) {
                NSLog(@"收到终端回传学员ID");
                [timerA2 invalidate];
                [self disconnect];
                [self pushFlutterViewController_EventChannel];
            }
        }
    }
}

- (void)sendA2 {
    //    if (a2Times > 3) {
    //        NSLog(@"a2发3次无应答断开连接");
    //        [timerA2 invalidate];
    //        [self cutDownConnectAndBack];
    //    } else {
    //        NSLog(@"发送学员信息");
    [self send:sendA2Message];
    NSLog(@"%@",sendA2Message);
    //        a2Times++;
    //    }
}

- (void)pushFlutterViewController_EventChannel {
    // 扫码成功后的回调
    self.result(@"successToConnect");
}



@end
